<?php

namespace app\common\service;
use app\common\model\AppConfig;
use think\Model;

/**
 * 签名验证类
 */
class SignService
{

    public static $stamp=1000000*120*1000;//时间戳过期时间----2分钟*1000000

    public function verifyRiderSign($params)
    {
        // 验证必传参数
        if (!isset($params['sign'])) {
            return ['status' => 0, 'msg' => '缺少签名参数'];
        }
        if (!isset($params['timestamp'])) {
            return ['status' => 0, 'msg' => '缺少时间戳参数'];
        }

        if (!isset($params['appid']) ) {
            return ['status' => 0, 'msg' => '缺少appid参数'];
        }
        // 验证时间戳是否过期
        $timestamp = $params['timestamp'];  //毫秒时间戳
        if (abs(time()*1000 - $timestamp) >self::$stamp) {
            return ['status' => 0, 'msg' => '请求已过期'];
        }
        $signParam = [];
        $signParam['timestamp'] = $timestamp;
        $signParam['appid'] = $params['appid'];

        // 获取客户端传来的签名
        $clientSign = $params['sign'];

        // 生成服务端签名
        $app_secret =AppConfig::where('appid', $signParam['appid'])->value('app_secret');
        if (empty($app_secret)){
            return ['status' => 0, 'msg' => 'appid不存在'];
        }
        $serverSign = $this->generateRiderSign($signParam, $app_secret);
        // var_dump($serverSign);exit;
        // 验证签名
        if ($clientSign !== $serverSign) {
            return ['status' => 0, 'msg' => '签名验证失败'];
        }

        return ['status' => 1, 'msg' => '签名验证成功'];
    }

    /**
     * 生成签名
     * @param array $params 参数数组
     * @param string $secret 密钥
     * @return string
     */
    protected function generateRiderSign(array $params, string $secret)
    {
        // 过滤空值
        $params = array_filter($params, function($value) {
            return $value !== '' && $value !== null;
        });

        // 按key升序排序
        ksort($params);

        // 拼接字符串
        $string = '';
        foreach ($params as $key => $value) {
            $string .= $key . '=' . $value . '&';
        }
        $string = rtrim($string, '&');

        // 拼接密钥并生成签名
        $string .= '&app_secret='.$secret;
        // var_dump(md5($string));exit;

        // 使用md5加密（也可以使用sha1）
        return strtoupper(md5($string));
    }
}